#ifndef __SCWIN32_H
#define __SCWIN32_H

#pragma warning (disable : 4267)

#define _POSIX_

#include <windows.h>
#include <winsock.h>
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <time.h>
#include <limits.h>

#define LOG_FUNC __FUNCTION__
#define ECONNREFUSED 0
#define UINT_FAST8_MAX 255
#define MAIN main

#ifdef LIBDYNAMIC

#define LIBEXPORTSYMBOL __declspec(dllexport)
#define LIBIMPORTSYMBOL __declspec(dllimport)

typedef void (*__scos_entrypoint)(void);

#if defined(LIBMAIN) || defined(LIBCTOR) || defined(LIBDTOR)
#ifdef LIBCTOR
void LIBCTOR(void);
#endif
#ifdef LIBDTOR
void LIBDTOR(void);
#endif
BOOL APIENTRY DllMain(HANDLE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved)
{
	static int clients = 0;
	
    switch( ul_reason_for_call ) {
		case DLL_PROCESS_ATTACH:
			printf("DLL_PROCESS_ATTACH for %p (currently %d clients)\n", hModule, clients);
			if (clients == 0)
			{
				printf("Constructing module %p\n", hModule);
#ifdef LIBCTOR
				LIBCTOR();
#endif /* LIBCTOR */
			}
			clients++;
			break;
		case DLL_PROCESS_DETACH:
			printf("DLL_PROCESS_DETACH for %p (currently %d clients)\n", hModule, clients);
			if (clients == 1)
			{
				printf("Destructing module %p\n", hModule);
#ifdef LIBDTOR
				LIBDTOR();
#endif /* LIBDTOR */
			}
			clients--;
    }
    return TRUE;
}

#undef LIBCTOR
#define LIBCTOR
#undef LIBDTOR
#define LIBDTOR
#endif /* LIBMAIN */

#else

#undef LIBIMPORTSYMBOL
#define LIBIMPORTSYMBOL
#undef LIBEXPORTSYMBOL
#define LIBEXPORTSYMBOL
#undef LIBCTOR
#define LIBCTOR
#undef LIBDTOR
#define LIBDTOR

#endif /* LIBDYNAMIC */

#undef LIBSYMBOL
#ifdef __LIBSCOS
#define LIBSYMBOL LIBEXPORTSYMBOL
#else
#define LIBSYMBOL LIBIMPORTSYMBOL
#endif /* __LIBSCOS */

typedef pthread_mutex_t scos_mutex_t;
typedef pthread_t       scos_thread_t;
typedef pthread_cond_t  scos_cond_t;
typedef pthread_key_t   scos_key_t;
typedef time_t          suseconds_t;
typedef char            int_fast8_t;
typedef unsigned char   uint_fast8_t;
typedef unsigned char   uint8_t;

#define scos_thread_create(thread, func, arg) pthread_create(thread, NULL, func, (void*)arg)
#define scos_thread_join(thread)              pthread_join(*thread, NULL)
#define scos_mutex_init(mutex)                pthread_mutex_init(mutex, NULL)
#define scos_mutex_destroy(mutex)             pthread_mutex_destroy(mutex)
#define scos_mutex_lock(mutex)                pthread_mutex_lock(mutex)
#define scos_mutex_unlock(mutex)              pthread_mutex_unlock(mutex)
#define scos_mutex_trylock(mutex)             pthread_mutex_trylock(mutex)
#define scos_cond_init(cond)                  pthread_cond_init(cond, NULL)
#define scos_cond_wait(cond, mutex)           pthread_cond_wait(cond, mutex)
#define scos_cond_signal(cond)                pthread_cond_signal(cond)

#define close                                 closesocket
#define strcasecmp                            _stricmp
#define strncasecmp                           _strnicmp

#ifdef __cplusplus
extern "C" {
#endif

LIBSYMBOL void scos_self_init(void);
LIBSYMBOL int  scos_self(void);
LIBSYMBOL void usleep(unsigned long int usec);
LIBSYMBOL int gettimeofday(struct timeval *tv, void *dummy);

#ifdef __cplusplus
}
#endif

#endif /* __SCWIN32_H */
